/*
    This file is part of Epoch <http://code.google.com/p/epoch/>.
    
    Copyright (C) 2011  Adam Meily <meily.adam@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#ifndef CLIENTHANDLER_H
#define CLIENTHANDLER_H

#include <Protocol.h>
#include <Certificate.h>
#include <Response.h>
//#include <Request.h>

#include <QtCore/QStack>

#include "Models/Device.h"
#include "Models/Revision.h"
#include "Models/Share.h"
#include "Models/Backup.h"

#include "Store/RecordStore.h"
#include "Config/ChronosConfig.h"
//#include "Chronos.h"

/*
 * sig -> client
 * sig -> delta
 * delta -> server
 * patch delta
 */

class ClientHandler : public Protocol
{
    Q_OBJECT
    
public:
    enum ClientState
    {
        WaitingForCert = 0x00,
        Ready = 0x01,
        WaitingForListing = 0x03,
        WaitingForDelta = 0x05,
        ReceivingDelta = 0x07
    };
    
    enum RawMode
    {
        Delta = 0x01,
        Full = 0x02
        //NewRevision = 0x04,
        //NewFile = 0x0c
    };
    //Q_DECLARE_FLAGS(RawMode, RawModeFlag);
    
    ClientHandler(int socket, const NodeConfig& config, RecordStore *store);
    virtual ~ClientHandler();
    
protected:
    virtual void onResponse(const Response& response);
    virtual void onRawMessage(const QByteArray& raw);
    virtual void onHandshakeComplete();
    virtual void onDisconnect();
    
    //int nextRecord();
    int next();
    int nextShare();
    int nextFile();
    int nextDir();
    int endSession();
    int begin();
    int authenticate(const Response& response);
    int listing(const Response& response);
    int delta(const Response& response);
    void deltaDone();
    
private:
    Revision m_currentFile;
    QString m_currentDir;
    QStack<Revision> m_fileStack;
    QStack<QString> m_directoryStack;
    QStack<Share> m_shareStack;
    Backup m_backup;
    RecordStore *m_store;
    Chronos *m_chronos;
    
    ClientState m_state;
    quint64 m_rawBytesReceived;
    quint64 m_rawBytesNeeded;
    RawMode m_rawMode;
    QFile m_rawStream;
    Device m_device;;
};

#endif // CLIENTHANDLER_H
